home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / elm / elm2.4 / src / file_util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-03  |  7.4 KB  |  285 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: file_util.c,v 5.6 1993/02/03 19:06:31 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 5.6 $   $State: Exp $
  6.  *
  7.  *            Copyright (c) 1988-1992 USENET Community Trust
  8.  *            Copyright (c) 1986,1987 Dave Taylor
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log: file_util.c,v $
  17.  * Revision 5.6  1993/02/03  19:06:31  syd
  18.  * Remove extra strchr/strcat/strcpy et al declarations
  19.  * From: Syd
  20.  *
  21.  * Revision 5.5  1993/01/20  03:37:16  syd
  22.  * Nits and typos in the NLS messages and corresponding default messages.
  23.  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
  24.  *
  25.  * Revision 5.4  1992/12/16  14:30:52  syd
  26.  * Make forward to checking consistent on sign ignoring
  27.  * From: Syd
  28.  *
  29.  * Revision 5.3  1992/12/11  01:45:04  syd
  30.  * remove sys/types.h include, it is now included by defs.h
  31.  * and this routine includes defs.h or indirectly includes defs.h
  32.  * From: Syd
  33.  *
  34.  * Revision 5.2  1992/11/26  00:46:13  syd
  35.  * changes to first change screen back (Raw off) and then issue final
  36.  * error message.
  37.  * From: Syd
  38.  *
  39.  * Revision 5.1  1992/10/03  22:58:40  syd
  40.  * Initial checkin as of 2.4 Release at PL0
  41.  *
  42.  *
  43.  ******************************************************************************/
  44.  
  45. /** File oriented utility routines for ELM 
  46.  
  47. **/
  48.  
  49. #include "headers.h"
  50. #include "s_elm.h"
  51. #include <sys/stat.h>
  52. #include <ctype.h>
  53. #include <errno.h>
  54.  
  55. #ifdef BSD
  56. # undef tolower
  57. #endif
  58.  
  59. #include <errno.h>
  60.  
  61. #ifdef BSD
  62. # include <sys/wait.h>
  63. #endif
  64.  
  65. extern int errno;        /* system error number */
  66.  
  67. char *error_description(), *getlogin();
  68. long  fsize();
  69.  
  70. long
  71. bytes(name)
  72. char *name;
  73. {
  74.     int err;
  75.     /** return the number of bytes in the specified file.  This
  76.         is to check to see if new mail has arrived....  (also
  77.         see "fsize()" to see how we can get the same information
  78.         on an opened file descriptor slightly more quickly)
  79.     **/
  80.  
  81.     int ok = 1;
  82.     struct stat buffer;
  83.  
  84.     if (stat(name, &buffer) != 0)
  85.       if (errno != 2) {
  86.         err = errno;
  87.         MoveCursor(LINES, 0);
  88.         Raw(OFF);
  89.         dprint(1,(debugfile,
  90.              "Error: errno %s on fstat of file %s (bytes)\n", 
  91.              error_description(err), name));
  92.         printf(catgets(elm_msg_cat, ElmSet, ElmErrorFstat,
  93.              "\nError attempting fstat on file %s!\n"),
  94.              name);
  95.         printf("** %s. **\n", error_description(err));
  96.         emergency_exit();
  97.       }
  98.       else
  99.         ok = 0;
  100.     
  101.     return(ok ? (long) buffer.st_size : 0L);
  102. }
  103.  
  104. int
  105. copy(from, to)
  106. char *from, *to;
  107. {
  108.     /** this routine copies a specified file to the destination
  109.         specified.  Non-zero return code indicates that something
  110.         dreadful happened! **/
  111.  
  112.     FILE *from_file, *to_file;
  113.     char buffer[VERY_LONG_STRING];
  114.     int  len;
  115.     
  116.     if ((from_file = fopen(from, "r")) == NULL) {
  117.       dprint(1, (debugfile, "Error: could not open %s for reading (copy)\n",
  118.          from));
  119.       error1(catgets(elm_msg_cat, ElmSet, ElmCouldNotOpenFile,
  120.         "Could not open file %s."), from);
  121.       return(1);
  122.     }
  123.  
  124.     if ((to_file = fopen(to, "w")) == NULL) {
  125.       dprint(1, (debugfile, "Error: could not open %s for writing (copy)\n",
  126.          to));
  127.       error1(catgets(elm_msg_cat, ElmSet, ElmCouldNotOpenFile,
  128.         "Could not open file %s."), to);
  129.       return(1);
  130.     }
  131.  
  132.     while (len = fread(buffer, 1, VERY_LONG_STRING, from_file))
  133.       if (fwrite(buffer, 1, len, to_file) != len) {
  134.           Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmWriteFailedCopy,
  135.               "\n\rWrite failed to temp file in copy\n\r"), 0);
  136.           perror(to);
  137.           fclose(to_file);
  138.           fclose(from_file);
  139.           return(1);
  140.       }
  141.     fclose(from_file);
  142.         if (fclose(to_file) == EOF) {
  143.       Write_to_screen(catgets(elm_msg_cat, ElmSet, ElmCloseFailedCopy,
  144.           "\n\rClose failed on temp file in copy\n\r"), 0);
  145.       perror(to);
  146.       return(1);
  147.     }
  148.     chown( to, userid, groupid);
  149.  
  150.     return(0);
  151. }
  152.  
  153. int
  154. append(fd, filename, prefix_str)
  155. FILE *fd;
  156. char *filename;
  157. char *prefix_str;
  158. {
  159.     /** This routine appends the specified file to the already
  160.         open file descriptor.. Returns non-zero if fails.  **/
  161.  
  162.     FILE *my_fd;
  163.     char buffer[VERY_LONG_STRING];
  164.     int  len;
  165.     
  166.     if ((my_fd = fopen(filename, "r")) == NULL) {
  167.       dprint(1, (debugfile,
  168.         "Error: could not open %s for reading (append)\n", filename));
  169.       return(1);
  170.     }
  171.  
  172.     if (prefix_str != NULL && fputs(prefix_str, fd) == EOF) {
  173.       MoveCursor(LINES, 0);
  174.       Raw(OFF);
  175.       printf(catgets(elm_msg_cat, ElmSet, ElmWriteFailedAppend,
  176.         "\nWrite failed to temp file in append\n"));
  177.       perror(filename);
  178.       rm_temps_exit();
  179.     }
  180.  
  181.     while (len = fread(buffer, 1, VERY_LONG_STRING, my_fd))
  182.       if (fwrite(buffer, 1, len, fd) != len) {
  183.           MoveCursor(LINES, 0);
  184.           Raw(OFF);
  185.           printf(catgets(elm_msg_cat, ElmSet, ElmWriteFailedAppend,
  186.               "\nWrite failed to temp file in append\n"));
  187.           perror(filename);
  188.           rm_temps_exit();
  189.       }
  190.  
  191.     if (fclose(my_fd) == EOF) {
  192.       MoveCursor(LINES, 0);
  193.       Raw(OFF);
  194.       printf(catgets(elm_msg_cat, ElmSet, ElmCloseFailedAppend,
  195.           "\nClose failed on temp file in append\n"));
  196.       perror(filename);
  197.       rm_temps_exit();
  198.     }
  199.  
  200.     return(0);
  201. }
  202.  
  203. #define FORWARDSIGN    "Forward to "
  204. int
  205. check_mailfile_size(mfile)
  206. char *mfile;
  207. {
  208.     /** Check to ensure we have mail.  Only used with the '-z'
  209.         starting option. So we output a diagnostic if there is
  210.         no mail to read (including  forwarding).
  211.         Return 0 if there is mail,
  212.            <0 if no permission to check,
  213.            1 if no mail,
  214.            2 if no mail because mail is being forwarded.
  215.      **/
  216.  
  217.     char firstline[SLEN];
  218.     int retcode;
  219.     struct stat statbuf;
  220.     FILE *fp = NULL;
  221.  
  222.     /* see if file exists first */
  223.     if (access(mfile, ACCESS_EXISTS) != 0)
  224.       retcode = 1;                    /* no file */
  225.  
  226.     /* exists - now see if user has read access */
  227.     else if (can_access(mfile, READ_ACCESS) != 0)
  228.       retcode = -1;                    /* no perm */
  229.  
  230.     /* read access - now see if file has a reasonable size */
  231.     else if ((fp = fopen(mfile, "r")) == NULL)
  232.       retcode = -1;        /* no perm? should have detected this above! */
  233.     else if (fstat(fileno(fp), &statbuf) == -1) 
  234.       retcode = -1;                    /* arg error! */
  235.     else if (statbuf.st_size < 2)        
  236.       retcode = 1;    /* empty or virtually empty, e.g. just a newline */
  237.  
  238.     /* file has reasonable size - see if forwarding */
  239.     else if (mail_gets (firstline, SLEN, fp) == 0)
  240.       retcode = 1;         /* empty? should have detected this above! */
  241.     else if (first_word_nc(firstline, FORWARDSIGN))
  242.       retcode = 2;                    /* forwarding */
  243.  
  244.     /* not forwarding - so file must have some mail in it */
  245.     else
  246.       retcode = 0;
  247.  
  248.     /* now display the appropriate message if there isn't mail in it */
  249.     switch(retcode) {
  250.  
  251.     case -1:    printf(catgets(elm_msg_cat, ElmSet, ElmNoPermRead,
  252.                 "You have no permission to read %s!\n\r"),
  253.                 mfile);
  254.             break;
  255.     case 1:        printf(catgets(elm_msg_cat, ElmSet, ElmNoMail,
  256.                 "You have no mail.\n\r"));
  257.             break;
  258.     case 2:        no_ret(firstline) /* remove newline before using */
  259.             printf(catgets(elm_msg_cat, ElmSet,ElmMailBeingForwarded,
  260.                 "Your mail is being forwarded to %s.\n\r"),
  261.               firstline + strlen(FORWARDSIGN));
  262.             break;
  263.     }
  264.     if (fp)
  265.       fclose(fp);
  266.  
  267.     return(retcode);
  268. }
  269.  
  270.  
  271. long fsize(fd)
  272. FILE *fd;
  273. {
  274.     /** return the size of the current file pointed to by the given
  275.         file descriptor - see "bytes()" for the same function with
  276.         filenames instead of open files...
  277.     **/
  278.  
  279.     struct stat buffer;
  280.  
  281.     (void) fstat(fileno(fd), &buffer);
  282.  
  283.     return( (long) buffer.st_size );
  284. }
  285.